﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _5._04对连续的异步任务使用await操作符
{
    class Program
    {
        static void Main(string[] args)
        {
            Task t = AsynchronyWithTPL();
            t.Wait();

            t = AsynchronyWithAwait();
            t.Wait();

            Console.ReadLine();
        }
        static Task AsynchronyWithTPL()
        {
            var containerTask = new Task(() =>
              {
                  Task<string> t = GetInfoAsync("TPL 1");
                  t.ContinueWith(task => {
                      Console.WriteLine(t.Result);
                      Task<string> t2 = GetInfoAsync("TPL 2");
                      t2.ContinueWith(innerTask => Console.WriteLine(innerTask.Result), TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.AttachedToParent);
                      t2.ContinueWith(innerTask => Console.WriteLine(innerTask.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);

                  }, TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.AttachedToParent);
                  t.ContinueWith(task => Console.WriteLine(task.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);
              });
            containerTask.Start();
            return containerTask;
        }

        /// <summary>
        /// 使用await后，C#立即创建了一个任务，其有一个后续操作任务，包含了await操作符后面的所有剩余代码
        /// 这个新任务也处理了异常传播，然后，将任务返回到主方法中并等待其完成
        /// </summary>
        /// <returns></returns>
        async static Task AsynchronyWithAwait()
        {
            try
            {
                string result = await GetInfoAsync("Async 1");
                Console.WriteLine(result);
                result = await GetInfoAsync("Async 2");
                Console.WriteLine(result);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        private async static Task<string> GetInfoAsync(string name)
        {
            Console.WriteLine($"Task {name} started!");
            await Task.Delay(TimeSpan.FromSeconds(2));
            if (name == "TPL 2") throw new Exception("Boom!");
            //throw new Exception("Boom!");
            return $"Task {name} is running on a thread id {Thread.CurrentThread.ManagedThreadId}, Is thread pool thread: {Thread.CurrentThread.IsThreadPoolThread}";
        }
    }
}
